#ifndef __OS_CORE_H__
#define __OS_CORE_H__

#include "os_config.h"
#include "os_port.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef struct os_core_tcb
{
    uint16_t                                                                                 pc;          // Program Counter
    uint32_t                                                                               tick;          // Tick Counter
    uint8_t                                                                               yield;
}os_core_tcb_st;

typedef int (* pf_task_func_t)                                               (void * const arg);

typedef struct os_thread
{
    os_core_tcb_st                                                                          tcb;          // Task Control Block
    pf_task_func_t                                                                    task_func;          // Task Function Pointer
    void   OS_THREAD_MEMORY                                                              *  arg;
    int8_t                                                                            init_flag;
}os_thread_st;

typedef struct os_thread_managerk
{
    os_thread_st                                                    thread_list[MAX_THREAD_NUM];           // Current Running Thread
}os_thread_manager_st;

/*-------------------------------------核心宏-------------------------------------------------*/
#define OS_WAIT_FOREVER                                                            (0xFFFFFFFFU)           //等待永远不超时

#define CUR_THREAD                   (&g_thread_manager.thread_list[g_current_thread_index].tcb)

#define OS_TASK_BEGAIN                { char os_is_yield = 1; switch((CUR_THREAD)->pc) {default:
#define OS_TASK_END                }(CUR_THREAD)->pc = 0; os_is_yield = 0; return os_is_yield; }

//任务等待：当cond满足退出等待
#define OS_TASK_WAIT(cond)                                                                     \
    do {                                                                                       \
        (CUR_THREAD)->pc = __LINE__; case __LINE__:                                            \
        if (!(cond)) return 0;                                                                 \
    } while (0)

//任务超时等待：当cond满足或者超时退出等待
#define OS_TASK_WAIT_TIMEOUT(cond, timeout_ms, p_ret)                                          \
    do {                                                                                       \
        (CUR_THREAD)->tick = port_GET_SYS_TICK();                                              \
        (CUR_THREAD)->pc = __LINE__; case __LINE__:                                            \
        if ((!(cond)) && (!(port_GET_SYS_TICK() - (CUR_THREAD)->tick > timeout_ms))) return 0; \
        else if((port_GET_SYS_TICK() - (CUR_THREAD)->tick) > timeout_ms) *(p_ret) = -1;        \
        else *(p_ret) = 0;                                                                     \
    } while (0)

//任务超时等待(不休眠)：当cond满足或者超时退出等待
#define OS_TASK_WAIT_TIMEOUT_WAKE(cond, timeout_ms, p_ret)                                     \
    do {                                                                                       \
        (CUR_THREAD)->tick = port_GET_SYS_TICK();                                              \
        (CUR_THREAD)->pc = __LINE__; case __LINE__:                                            \
        if ((!(cond)) && (!(port_GET_SYS_TICK() - (CUR_THREAD)->tick > timeout_ms))) return 1; \
        else if((port_GET_SYS_TICK() - (CUR_THREAD)->tick) > timeout_ms) *(p_ret) = -1;        \
        else *(p_ret) = 1;                                                                     \
    } while (0)

//任务主动放弃cpu
#define OS_TASK_YIELD()                                                                        \
    do {                                                                                       \
        (CUR_THREAD)->pc = __LINE__; (CUR_THREAD)->yield  = 1; case __LINE__:                  \
        if((CUR_THREAD)->yield) { (CUR_THREAD)->yield = 0; return 1; }                         \
    } while (0)

//睡眠：
#define os_sleep(ms)                                                                           \
    do {                                                                                       \
        (CUR_THREAD)->tick = port_GET_SYS_TICK();                                              \
        (CUR_THREAD)->pc = __LINE__; case __LINE__:                                            \
        if (!(port_GET_SYS_TICK() - (CUR_THREAD)->tick > (ms) )) return 0;                     \
    } while (0)

//延时:但是不睡眠
#define os_delay(ms)                                                                           \
    do {                                                                                       \
        (CUR_THREAD)->tick = port_GET_SYS_TICK();                                              \
        (CUR_THREAD)->pc = __LINE__; case __LINE__:                                            \
        if (!(port_GET_SYS_TICK() - (CUR_THREAD)->tick > (ms) )) return 1;                     \
    } while (0)
/*-------------------------------------核心宏-------------------------------------------------*/

extern volatile uint32_t              OS_THREAD_MEMORY                   g_current_thread_index;
extern volatile os_thread_manager_st  OS_THREAD_MEMORY                         g_thread_manager;

extern void os_enter_critical(void);
extern void os_exit_critical(void);

extern void isr_enter_critical(void);
extern void isr_exit_critical(void);

#ifdef __cplusplus
}
#endif
#endif
